﻿// Fill out your copyright notice in the Description page of Project Settings.


#include "AsyncBlueprintNode/AsyncCountdown.h"

void UMyBPAsyncAction::Activate()
{
	// 开新的线程，测试 Activate 调用情况
	Async(EAsyncExecution::ThreadPool, [&]()
	{
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Start Delay 1s."));
		FPlatformProcess::Sleep(1.0f);
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Delay Finished."));
	});
}

UMyBPAsyncAction* UMyBPAsyncAction::AsyncCountdown(UObject* WorldContextObject, AAsyncTickActor* AsyncTickActor, int32 StartNum)
{
	if (WorldContextObject == nullptr)
	{
		FFrame::KismetExecutionMessage(TEXT("Invalid WorldContextObject"), ELogVerbosity::Error);
		// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Invalid WorldContextObject."));
		return nullptr;
	}

	UMyBPAsyncAction* MyBPAsyncActionNode = NewObject<UMyBPAsyncAction>();
	// Lambda 表达式
	auto CountdownFunc = [&,MyBPAsyncActionNode, WorldContextObject, AsyncTickActor, StartNum]()
	{
		if (IsValid(AsyncTickActor))
		{
			if (AsyncTickActor->CountdownNums.Num() == StartNum)
			{
				// OnSucceeded输出节点
				MyBPAsyncActionNode->OnSucceeded.Broadcast(1);

				// 清空定时器
				WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(MyBPAsyncActionNode->TimerHandle);

				// 如果不使用，则销毁
				MyBPAsyncActionNode->SetReadyToDestroy();
				// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Countdown Completed."));
			} else
			{
				int32 length = AsyncTickActor->CountdownNums.Num();
				AsyncTickActor->CountdownNums.Add(length + 1);
				// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Counting down... %d"), length + 1);
			}
		} else
		{
			// OnFailed 输出节点
			MyBPAsyncActionNode->OnFailed.Broadcast(-1);
			WorldContextObject->GetWorld()->GetTimerManager().ClearTimer(MyBPAsyncActionNode->TimerHandle);
			// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Invalid AsyncTickActor."));
			FFrame::KismetExecutionMessage(TEXT("Invalid AsyncTickActor"), ELogVerbosity::Error);
		}
	};

	// 设置定时器并开始
	WorldContextObject->GetWorld()->GetTimerManager().SetTimer(MyBPAsyncActionNode->TimerHandle, FTimerDelegate::CreateLambda(CountdownFunc), 1.0f, true);
	// UE_LOG(LogTemp, Warning, TEXT(__FUNCTION__" Countdown Starting."));
	return MyBPAsyncActionNode;
}
